#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "sha1.h"
#include "md5.h"
//#include "hmac.h"
/**
 * Perform HMAC-MD5
 * NOTE: does not handle keys larger than the block size.
 */
void hmac_md5 (const uint8_t *msg, int length, const uint8_t *key, int key_len, uint8_t *digest)
{
    MD5_CTX context;
    uint8_t k_ipad[64];
    uint8_t k_opad[64];
    int i;

    memset(k_ipad, 0, sizeof k_ipad);
    memset(k_opad, 0, sizeof k_opad);
    memcpy(k_ipad, key, key_len);
    memcpy(k_opad, key, key_len);

    for (i = 0; i < 64; i++) 
    {
        k_ipad[i] ^= 0x36;
        k_opad[i] ^= 0x5c;
    }

    MD5Init   (&context);
    MD5Update (&context, k_ipad, 64);
    MD5Update (&context, (uint8_t*)msg, length);
    MD5Final  (&context, digest);
    MD5Init   (&context);
    MD5Update (&context, k_opad, 64);
    MD5Update (&context, digest, 16);
    MD5Final  (&context, digest);
}

/**
 * Perform HMAC-SHA1
 * NOTE: does not handle keys larger than the block size.
 */
void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key, int key_len, uint8_t *digest)
{

    struct sha1_ctx context;
    uint8_t k_ipad[64];
    uint8_t k_opad[64];
    int i;

    memset(k_ipad, 0, sizeof k_ipad);
    memset(k_opad, 0, sizeof k_opad);
    memcpy(k_ipad, key, key_len);
    memcpy(k_opad, key, key_len);

    for (i = 0; i < 64; i++) 
    {
        k_ipad[i] ^= 0x36;
        k_opad[i] ^= 0x5c;
    }

    sha1_init_ctx (&context);
    sha1_process_block (k_ipad, 64, &context);
    sha1_process_bytes (msg, length, &context);
    sha1_finish_ctx    (&context, digest);
    sha1_init_ctx      (&context);
    sha1_process_block (k_opad, 64, &context);
    sha1_process_bytes (digest, 20, &context);
    sha1_finish_ctx    (&context, digest); 
}
